﻿using System;
using System.IO;
using System.IO.Compression;
using System.Web.UI;

namespace Blazing.Web.Util
{
    public class ViewstateCompressionHelper
    {
        public static object LoadPageStateFromPersistenceMedium(Page page)
        {
            string viewState = page.Request.Form["__VSTATE"];
            byte[] bytes = Convert.FromBase64String(viewState);
            bytes = Decompress(bytes);
            LosFormatter formatter = new LosFormatter();
            return formatter.Deserialize(Convert.ToBase64String(bytes));
        }

        public static void SavePageStateToPersistenceMedium(Page page, object viewState)
        {
            LosFormatter formatter = new LosFormatter();
            StringWriter writer = new StringWriter();
            formatter.Serialize(writer, viewState);
            string viewStateString = writer.ToString();
            byte[] bytes = Convert.FromBase64String(viewStateString);
            bytes = Compress(bytes);
            if(ScriptManager.GetCurrent(page) == null)
                page.ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
            else
                ScriptManager.RegisterHiddenField(page, "__VSTATE", Convert.ToBase64String(bytes));
        }

        public static byte[] Compress(byte[] data)
        {
            MemoryStream output = new MemoryStream();
            DeflateStream deflate = new DeflateStream(output,
                              CompressionMode.Compress, true);
            deflate.Write(data, 0, data.Length);
            deflate.Close();
            return output.ToArray();
        }

        public static byte[] Decompress(byte[] data)
        {
            MemoryStream input = new MemoryStream();
            input.Write(data, 0, data.Length);
            input.Position = 0;
            DeflateStream deflate = new DeflateStream(input,
                              CompressionMode.Decompress, true);
            MemoryStream output = new MemoryStream();
            byte[] buff = new byte[512];
            int read = -1;
            read = deflate.Read(buff, 0, buff.Length);
            while (read > 0)
            {
                output.Write(buff, 0, read);
                read = deflate.Read(buff, 0, buff.Length);
            }
            deflate.Close();
            return output.ToArray();
        }
    }
}
